import type { ActionType, ProColumns } from '@ant-design/pro-components';
import {
  arrayMoveImmutable,
  EditableProTable,
  ProCard,
  ProFormField,
  useRefFunction,
} from '@ant-design/pro-components';
import { Button, Input } from 'antd';
import React, { useEffect, useRef, useState } from 'react';
import {
  SortableContainer,
  SortableElement,
  SortableHandle,
} from 'react-sortable-hoc';
import './drag.less';
import { MenuOutlined } from '@ant-design/icons';
import { EditableFormInstance } from '@ant-design/pro-table/lib/components/EditableTable';
import { uuid } from '@antv/x6/lib/util/string/uuid';

const DragHandle = SortableHandle(() => (
  <MenuOutlined style={{ cursor: 'grab', color: '#999' }} />
));
type DataSourceType = {
  id: React.Key;
  title?: string;
  decs?: string;
  state?: string;
  created_at?: string;
  children?: DataSourceType[];
};

const defaultData: DataSourceType[] = new Array(1).fill(1).map((_, index) => {
  return {
    id: (Date.now() + index).toString(),
    title: `活动名称${index}`,
    decs: '这个活动真好玩',
    state: 'open',
    created_at: '1590486176000',
  };
});

export default () => {
  const [editableKeys, setEditableRowKeys] = useState<React.Key[]>(() =>
    defaultData.map((item) => item.id),
  );
  const data = useRef(defaultData);
  const actionRef = useRef<ActionType>();
  const editableFormRef = useRef<EditableFormInstance>();
  const [dataSource, setDataSource] = useState<DataSourceType[]>(defaultData);
  const SortableItem = SortableElement((props: any) => <tr {...props} />);
  const SortContainer = SortableContainer((props: any) => <tbody {...props} />);
  const onSortEnd = useRefFunction(
    ({ oldIndex, newIndex }: { oldIndex: number; newIndex: number }) => {
      if (oldIndex !== newIndex) {
        const newData = arrayMoveImmutable(
          [...dataSource],
          oldIndex,
          newIndex,
        ).filter((el) => !!el);
        setDataSource([...newData]);
      }
    },
  );

  const DraggableContainer = (props: any) => {
    return (
      <SortContainer
        key={'1'}
        useDragHandle
        disableAutoscroll
        helperClass="row-dragging"
        onSortEnd={onSortEnd}
        {...props}
      />
    );
  };

  const DraggableBodyRow = (props: any) => {
    const { className, style, ...restProps } = props;
    // function findIndex base on Table rowKey props and should always be a right array index
    const index = dataSource.findIndex(
      (x) => x.id === restProps['data-row-key'],
    );
    return (
      <SortableItem key={dataSource[index]?.id} index={index} {...restProps} />
    );
  };
  const columns: ProColumns<DataSourceType>[] = [
    {
      title: '排序',
      dataIndex: 'sort',
      width: 60,
      className: 'drag-visible',
      renderFormItem: () => <DragHandle />,
    },
    {
      title: '活动名称',
      dataIndex: 'title',
      width: '30%',
      formItemProps: {
        rules: [
          {
            required: true,
            whitespace: true,
            message: '此项是必填项',
          },
          {
            message: '必须包含数字',
            pattern: /[0-9]/,
          },
          {
            max: 16,
            whitespace: true,
            message: '最长为 16 位',
          },
          {
            min: 6,
            whitespace: true,
            message: '最小为 6 位',
          },
        ],
      },
    },
    {
      title: '状态',
      key: 'state',
      dataIndex: 'state',
      valueType: 'select',
      valueEnum: {
        all: { text: '全部', status: 'Default' },
        open: {
          text: '未解决',
          status: 'Error',
        },
        closed: {
          text: '已解决',
          status: 'Success',
        },
      },
    },
    {
      title: '描述',
      dataIndex: 'decs',
      renderFormItem: (d, { value }) => {
        // console.log(editableFormRef.current?.getRowData?(d?.entity?.id));
        return <Input />;
      },
    },
    {
      title: '操作',
      valueType: 'option',
      width: 250,
      render: () => {
        return null;
      },
    },
  ];

  useEffect(() => {
    data.current = defaultData;
    // setInterval(() => {
    //   setDataSource([...dataSource])
    // }, 2000)
  }, []);

  return (
    <>
      <Button
        type="primary"
        onClick={() => {
          actionRef.current?.addEditRecord?.(
            {
              id: (Math.random() * 1000000).toFixed(0),
              title: '',
            },
            { newRecordType: 'dataSource' },
          );
        }}
      >
        新建一行
      </Button>
      <EditableProTable<DataSourceType>
        headerTitle="可编辑表格"
        actionRef={actionRef}
        editableFormRef={editableFormRef}
        columns={columns}
        recordCreatorProps={false}
        rowKey="id"
        scroll={{
          x: 960,
        }}
        // recordCreatorProps={{
        //   newRecordType: 'dataSource',
        //   record: (index) => {
        //     return { id: (Date.now() + index).toString(), };
        //   },
        // }}
        defaultValue={data.current}
        toolBarRender={() => {
          return [
            <Button
              type="primary"
              key="save"
              onClick={() => {
                // dataSource 就是当前数据，可以调用 api 将其保存
                console.log(data.current);
              }}
            >
              保存数据
            </Button>,
          ];
        }}
        editable={{
          type: 'multiple',
          editableKeys,
          actionRender: (row, config, defaultDoms) => {
            return [defaultDoms.delete];
          },
          onValuesChange: (record, recordList) => {
            // editableFormRef.current?.setRowData?.(record.id, record)
            console.log(editableFormRef.current?.getFieldsValue());

            // data.current = recordList;
            // setDataSource(recordList);
            editableFormRef.current?.setFieldsValue?.(
              recordList.reduce((p, n) => {
                return {
                  ...p,
                  [n.id]: n,
                };
              }, {}),
            );
          },
          onChange: setEditableRowKeys,
        }}
        components={{
          body: {
            wrapper: (props: any) => (
              <DraggableContainer key={'u'} {...props} />
            ),
            row: (props: any) => <DraggableBodyRow key={'r'} {...props} />,
          },
        }}
      />
      <ProCard title="表格数据" headerBordered collapsible defaultCollapsed>
        <ProFormField
          ignoreFormItem
          fieldProps={{
            style: {
              width: '100%',
            },
          }}
          mode="read"
          valueType="jsonCode"
          text={JSON.stringify(dataSource)}
        />
      </ProCard>
    </>
  );
};
